home *** CD-ROM | disk | FTP | other *** search
- //$Id: fbutton.cc 1.4 1998/04/08 15:11:45 dlorre Exp dlorre $
- #include <intuition/intuition.h>
- #include <intuition/classes.h>
- #include <intuition/classusr.h>
- #include <intuition/imageclass.h>
- #include <intuition/gadgetclass.h>
- #include <intuition/icclass.h>
- #include <intuition/cghooks.h>
- #include <libraries/gadtools.h>
-
- #include <string.h>
- #include <stdio.h>
- #include <mydebug.h>
-
- #include "screen.h"
- #include "window.h"
- #include "gadgets/fbutton.h"
- #include "gadgets/eclass.h"
- #include "gadgetlist.h"
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <proto/utility.h>
- #include <clib/alib_protos.h>
- #include <compiler.h>
-
- static int InitBoxImage(void) ;
- static void FreeBoxImage(void) ;
- static struct Image *BoxImage ;
-
-
- // Ces déclarations ne sont plus statiques puisque la classe devient globale
-
- Class *BOOPSIfbutton ;
- int InitFButton(void) ;
- void FreeFButton(void) ;
-
- extern "C" STDARGS ULONG HookEntry() ;
-
-
- // ========================================================================
- // ========================== FBUTTON CLASS ===============================
- // ========================================================================
-
- fbutton::fbutton(gadgetlist *gl,
- void (window::*func)(gadget *, unsigned long, unsigned short),
- const char *t, BOOL def, BOOL disable) : gadget(gl, func),
- it1(NULL), it2(NULL), it3(NULL),
- norm1(NULL), norm2(NULL), under(NULL),
- font(NULL), underline(NULL)
- {
- InitBoxImage() ;
- InitFButton() ;
-
- if (t) {
- if (def) glist->setdefault(TRUE) ;
- initlab(t) ;
- }
-
- gad = gl->gad = (Gadget *)NewObject(BOOPSIfbutton, NULL,
- GA_ID, id,
- GA_Top, gl->ng->ng_TopEdge,
- GA_Left, gl->ng->ng_LeftEdge,
- GA_Width, gl->ng->ng_Width,
- GA_Height, gl->ng->ng_Height,
-
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
-
- GA_Previous, gl->gad,
- GA_IntuiText, it1 ,
- GA_Image, BoxImage,
-
- GA_UserData, EGA_Pulse,
- GA_Disabled, disable,
- EGA_XPens, gl->win->ws->xpens,
-
- TAG_END) ;
-
- if (def) gl->setdefault(FALSE) ;
- }
-
- fbutton::~fbutton()
- {
- freelab() ;
- if (gad) DisposeObject(gad) ;
- FreeFButton() ;
- FreeBoxImage() ;
- }
-
- void fbutton::select(BOOL sel, BOOL disable)
- {
- SetGadgetAttrs((Gadget *)gad, w, NULL,
- GA_Selected, sel,
- GA_Disabled, disable,
- TAG_END) ;
- RefreshGList((Gadget *)gad, w, NULL, 1);
- }
-
-
- void fbutton::keystroke(BOOL shifted)
- {
- select(TRUE) ;
- Delay(5) ;
- select(FALSE) ;
- Delay(5) ;
- gadget::action(NULL, NULL) ;
- }
-
- void fbutton::action(unsigned long classe, unsigned short code)
- {
- if (classe != IDCMP_GADGETDOWN) {
- gadget::action(classe, code) ;
- }
- }
-
-
- void fbutton::initlab(const char *t)
- {
- BOOL underset = FALSE ;
- int i, l1, l2 ;
-
- if (t) {
-
- it1 = new IntuiText ;
- it2 = new IntuiText ;
- it3 = new IntuiText ;
-
- underline = new TTextAttr ;
-
- it1->FrontPen = it2->FrontPen = it3->FrontPen = glist->gpen ;
- it1->BackPen = it2->BackPen = it3->BackPen = 0 ;
- it1->DrawMode = it2->DrawMode = it3->DrawMode = JAM1 ;
-
- norm1 = new char[strlen(t)+1] ;
- norm2 = new char[strlen(t)+1] ;
- under = new char[2] ;
-
- underkey(t) ;
-
- CopyMem(glist->ng->ng_TextAttr, underline, sizeof(struct TTextAttr)) ;
- underline->tta_Style |= FSF_UNDERLINED ;
- font = OpenFont((TextAttr *)underline) ;
-
- for (i=l1=l2=0; t[i]; i++) {
- if (t[i] == '_') {
- if (t[i+1]) under[0] = t[++i] ;
- underset = TRUE ;
- }
- else {
- if (underset) {
- norm2[l2++] = t[i] ;
- }
- else {
- norm1[l1++] = t[i] ;
- }
- }
- }
- norm1[l1] = '\0' ;
- norm2[l2] = '\0' ;
- under[1] = '\0' ;
-
- if (l1) {
- it1->IText = (UBYTE *)norm1 ;
- it1->ITextFont = glist->ng->ng_TextAttr ;
- if (underset) {
- it1->NextText = it2 ;
- it2->LeftEdge = short(IntuiTextLength(it1)) ;
- it2->IText = (UBYTE *)under ;
- it2->ITextFont = (TextAttr *)underline ;
- if (l2) {
- it2->NextText = it3 ;
- it3->LeftEdge = short(it2->LeftEdge + IntuiTextLength(it2)) ;
- it3->IText = (UBYTE *)norm2 ;
- it3->ITextFont = glist->ng->ng_TextAttr ;
- }
- }
- }
- else if (underset) {
- it1->IText = (UBYTE *)under ;
- it1->ITextFont = (TextAttr *)underline ;
- it1->NextText = it2 ;
- it2->LeftEdge = short(IntuiTextLength(it1)) ;
- it2->IText = (UBYTE *)norm2 ;
- it2->ITextFont = glist->ng->ng_TextAttr ;
- }
- }
- }
-
-
- void fbutton::freelab()
- {
- if (norm1) delete norm1 ;
- if (norm2) delete norm2 ;
- if (under) delete under ;
-
- if (it1) delete it1 ;
- if (it2) delete it2 ;
- if (it3) delete it3 ;
-
- if (underline) delete underline ;
-
- if (font) CloseFont(font) ;
- }
-
-
- void fbutton::set(const char *text)
- {
- if (text) {
- freelab() ;
- initlab(text) ;
- SetGadgetAttrs((Gadget *)gad, w, NULL,
- GA_IntuiText, it1,
- TAG_END) ;
- }
- }
-
-
- static int BoxImageCnt = 0 ;
- int InitBoxImage(void)
- {
- if (BoxImageCnt) {
- BoxImageCnt++ ;
- }
- else if (
- BoxImage = (struct Image *)NewObject(NULL, (UBYTE *)FRAMEICLASS,
- IA_FrameType, FRAME_BUTTON,
- IA_EdgesOnly, TRUE,
- TAG_END)) {
- BoxImageCnt = 1 ;
- }
- else
- BoxImageCnt = 0 ;
-
- return (BoxImageCnt) ;
- }
-
- void FreeBoxImage(void)
- {
- BoxImageCnt-- ;
- if (!BoxImageCnt) {
- // This is a DEFENSIVE programming test
- // i.e. not needed under normal conditions
- if (BoxImage) DisposeObject(BoxImage) ;
- }
- }
-
-
- // ========================================================================
- // =============================== FBUT ===================================
- // ========================================================================
-
- #define DRAW_NONE 0
- #define DRAW_IMAGE 1
- #define DRAW_INTUITEXT 2
- #define DRAW_TEXT 3
-
- struct FButtonINST {
- Image *LabelImage ;
- Image *Img ;
- IntuiText *IText ;
- STRPTR Text ;
- LONG Mode ;
- UWORD *XPens ;
- } ;
-
- static ULONG STDARGS dispatchFButton(Class *cl, Object *o, Msg msg);
-
- static void NotifyFButton(Class *, Object *, ULONG, long, gpInput *) ;
-
- static ULONG RenderFButton(Class *, Gadget *, gpRender *) ;
-
- static void FButtonLims(FButtonINST *inst, Gadget *g, GadgetInfo *gi) ;
-
- static int FButtonCnt = 0 ;
-
- static UWORD ditherData[] = { 0x5555, 0xAAAA } ;
-
- int InitFButton(void)
- {
- if (FButtonCnt) {
- FButtonCnt++ ;
- }
- else if (!(BOOPSIfbutton = MakeClass(NULL, (UBYTE *)GADGETCLASS, NULL,
- sizeof(FButtonINST), 0))) {
- FButtonCnt = 0 ;
- }
- else {
- BOOPSIfbutton->cl_Dispatcher.h_Entry = (HOOKFUNC)HookEntry ;
- BOOPSIfbutton->cl_Dispatcher.h_SubEntry = (HOOKFUNC)dispatchFButton;
- BOOPSIfbutton->cl_Dispatcher.h_Data = NULL ;
- FButtonCnt = 1 ;
- }
- return FButtonCnt ;
- }
-
- void FreeFButton(void)
- {
- FButtonCnt-- ;
- if (!FButtonCnt)
- if (BOOPSIfbutton) FreeClass(BOOPSIfbutton) ;
- }
-
- ULONG SAVEDS STDARGS dispatchFButton( Class *cl, Object *o, Msg msg)
- {
- FButtonINST *inst ;
- ULONG retval = FALSE ;
- Object *object ;
-
- GETA4 ;
- switch (msg->MethodID) {
- case OM_NEW:
- if (object = (Object *)DoSuperMethodA(cl, o, msg)) {
- inst = (FButtonINST *)INST_DATA(cl, object) ;
- if ( FindTagItem(GA_Image, ((opSet *)msg)->ops_AttrList)) {
- inst->Img = (Image *)GetTagData(GA_Image,
- NULL,
- ((opSet *)msg)->ops_AttrList) ;
- }
- inst->XPens = (UWORD *)GetTagData(EGA_XPens, NULL,
- ((opSet *)msg)->ops_AttrList) ;
- if ( FindTagItem(GA_Text, ((opSet *)msg)->ops_AttrList)) {
- inst->Text = (STRPTR)GetTagData(GA_Text,
- NULL,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_TEXT ;
- }
- else if ( FindTagItem(GA_LabelImage, ((opSet *)msg)->ops_AttrList)) {
- inst->LabelImage = (Image *)GetTagData(GA_LabelImage,
- NULL,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_IMAGE ;
- }
- else if ( FindTagItem(GA_IntuiText, ((opSet *)msg)->ops_AttrList)) {
- inst->IText = (IntuiText *)GetTagData(GA_IntuiText,
- NULL,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_INTUITEXT ;
- }
- else inst->Mode = DRAW_NONE ;
- retval = (ULONG)object ;
- }
- break ;
- case GM_HITTEST:
- retval = DoSuperMethodA(cl, o, msg) ;
- break ;
- case GM_GOACTIVE:
- {
- gpInput *gpi = (gpInput *)msg ;
- if (gpi->gpi_IEvent) {
- ((Gadget *)o)->Flags |= GFLG_SELECTED ;
- RenderFButton(cl, (Gadget *)o, (gpRender *)msg) ;
- retval = GMR_MEACTIVE ;
- }
- else
- retval = GMR_NOREUSE ;
- }
- break ;
- case GM_GOINACTIVE:
- ((Gadget *)o)->Flags &= ~GFLG_SELECTED ;
- RenderFButton(cl, (Gadget *)o, (gpRender *)msg) ;
- break ;
- case GM_HANDLEINPUT:
- {
- gpInput *gpi = (gpInput *)msg ;
- InputEvent *ie = gpi->gpi_IEvent ;
- Gadget *g = (Gadget *)o ;
- retval = GMR_MEACTIVE ;
-
- if (ie->ie_Class == IECLASS_RAWMOUSE) {
- switch (ie->ie_Code) {
- case SELECTUP:
- if ( (gpi->gpi_Mouse.X < 0) ||
- (gpi->gpi_Mouse.X > g->Width) ||
- (gpi->gpi_Mouse.Y < 0) ||
- (gpi->gpi_Mouse.Y > g->Height) ) {
- retval = GMR_NOREUSE ;
- }
- else {
- NotifyFButton(cl, o, 0, 0, (gpInput *)msg) ;
- retval = GMR_NOREUSE | GMR_VERIFY ;
- }
- break ;
- case MENUDOWN:
- retval = GMR_REUSE ;
- break ;
- default:
- retval = GMR_MEACTIVE ;
- }
- }
- else if (ie->ie_Class == IECLASS_TIMER) {
- if (( (gpi->gpi_Mouse.X < 0) ||
- (gpi->gpi_Mouse.X > g->Width) ||
- (gpi->gpi_Mouse.Y < 0) ||
- (gpi->gpi_Mouse.Y > g->Height) )) {
- if (g->Flags & GFLG_SELECTED) {
- g->Flags &= ~GFLG_SELECTED ;
- RenderFButton(cl, g, (gpRender *)msg) ;
- }
- }
- else {
- if (!(g->Flags & GFLG_SELECTED)) {
- g->Flags |= GFLG_SELECTED ;
- NotifyFButton(cl, o, OPUF_INTERIM, 0, (gpInput *)msg) ;
- RenderFButton(cl, g, (gpRender *)msg) ;
- }
- }
- }
- }
- break ;
- case OM_SET:
- retval = DoSuperMethodA(cl, o, msg) ;
- if ( FindTagItem(GA_Text, ((opSet *)msg)->ops_AttrList) ||
- FindTagItem(GA_IntuiText, ((opSet *)msg)->ops_AttrList) ||
- FindTagItem(GA_LabelImage, ((opSet *)msg)->ops_AttrList) ) {
- RastPort *rp ;
- Gadget *g = (Gadget *)o ;
-
- inst = (FButtonINST *)INST_DATA(cl, o) ;
-
- if ( FindTagItem(GA_Text, ((opSet *)msg)->ops_AttrList)) {
- inst->Text = (STRPTR)GetTagData(GA_Text,
- (ULONG)inst->Text,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_TEXT ;
- }
- else if ( FindTagItem(GA_LabelImage, ((opSet *)msg)->ops_AttrList)) {
- inst->LabelImage = (Image *)GetTagData(GA_LabelImage,
- (ULONG)inst->LabelImage,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_IMAGE ;
- }
- else if ( FindTagItem(GA_IntuiText, ((opSet *)msg)->ops_AttrList)) {
- inst->IText = (IntuiText *)GetTagData(GA_IntuiText,
- (ULONG)inst->IText,
- ((opSet *)msg)->ops_AttrList) ;
- inst->Mode = DRAW_INTUITEXT ;
- }
- if (rp = ObtainGIRPort( ((opSet *)msg)->ops_GInfo) ) {
-
- DoMethod(o, GM_RENDER, ((opSet *)msg)->ops_GInfo, rp, GREDRAW_REDRAW) ;
- ReleaseGIRPort(rp) ;
- }
- }
- break ;
- case GM_RENDER:
- retval = RenderFButton(cl, (Gadget *)o, (gpRender *)msg) ;
- break ;
- default :
- retval = DoSuperMethodA(cl, o, msg) ;
- break ;
- }
- return retval ;
- }
-
-
- void SAVEDS NotifyFButton(Class *cl, Object *o, ULONG flags, long level, gpInput *gpi)
- {
- static TagItem tt[3] ;
-
- GETA4 ;
- tt[0].ti_Tag = EGA_Pulse ;
- tt[0].ti_Data = level ;
-
- tt[1].ti_Tag = GA_ID ;
- tt[1].ti_Data = ((Gadget *)o)->GadgetID ;
-
- tt[2].ti_Tag = TAG_DONE ;
-
- DoSuperMethod(cl, o, OM_NOTIFY, tt, gpi->gpi_GInfo, flags) ;
- }
-
- ULONG SAVEDS RenderFButton(Class *cl, Gadget *g, gpRender *msg)
- {
- RastPort *rp ;
- ULONG retval = TRUE ;
- UWORD *pens = msg->gpr_GInfo->gi_DrInfo->dri_Pens ;
- FButtonINST *inst = (FButtonINST *)INST_DATA(cl, (Object *)g) ;
- ULONG state ;
- impDraw imp ;
- IntuiText *itext ;
- LONG l, t ;
- IBox cbox, fbox ;
- impFrameBox ifb ;
-
- GETA4 ;
- if (msg->MethodID == GM_RENDER)
- rp = msg->gpr_RPort ;
- else
- rp = ObtainGIRPort(msg->gpr_GInfo) ;
- if (rp) {
-
- if (g->Flags & GFLG_SELECTED)
- state = IDS_SELECTED ;
- else if (g->Flags & GFLG_DISABLED)
- state = IDS_DISABLED ;
- else
- state = IDS_NORMAL ;
-
- cbox.Left = g->LeftEdge ;
- cbox.Top = g->TopEdge ;
- cbox.Width = g->Width ;
- cbox.Height = g->Height ;
-
- ifb.MethodID = IM_FRAMEBOX ;
- ifb.imp_ContentsBox = &cbox ;
- ifb.imp_FrameBox = &fbox ;
- ifb.imp_DrInfo = msg->gpr_GInfo->gi_DrInfo ;
- ifb.imp_FrameFlags = NULL ;
- DoMethodA((Object *)inst->Img, (Msg)&ifb) ;
-
- SetAPen(rp, (g->Flags & GFLG_SELECTED)?pens[FILLPEN]:inst->XPens[BUTTONFILL_PEN]) ;
- RectFill(rp, g->LeftEdge, g->TopEdge,
- g->LeftEdge+g->Width-1, g->TopEdge+g->Height-1) ;
-
- imp.MethodID = IM_DRAWFRAME ;
- imp.imp_RPort = rp ;
- imp.imp_Offset.X = g->LeftEdge ;
- imp.imp_Offset.Y = g->TopEdge ;
- imp.imp_State = state ;
- imp.imp_DrInfo = msg->gpr_GInfo->gi_DrInfo ;
- imp.imp_Dimensions.Width = g->Width ;
- imp.imp_Dimensions.Height = g->Height ;
-
- DoMethodA((Object *)inst->Img, (Msg)&imp) ;
-
- if (state == IDS_DISABLED) {
- SetAPen(rp, 1) ;
- SetAfPt(rp, ditherData, 1) ;
- RectFill(rp, g->LeftEdge, g->TopEdge, g->LeftEdge+g->Width-1, g->TopEdge+g->Height-1) ;
- SetAfPt(rp, NULL, 0) ;
- }
-
- switch (inst->Mode) {
- case DRAW_NONE:
- break ;
- case DRAW_TEXT:
- Move(rp, g->LeftEdge, g->TopEdge+rp->TxBaseline) ;
- Text(rp, inst->Text, strlen(inst->Text)) ;
- break ;
- case DRAW_INTUITEXT:
- itext = inst->IText ;
- while (itext->NextText) itext = itext->NextText ;
- l = IntuiTextLength(itext) + itext->LeftEdge ;
- l = g->LeftEdge + 1 + (g->Width - l - 2) / 2 ;
- t = g->TopEdge + 1 + (g->Height - itext->ITextFont->ta_YSize -2) / 2 ;
- PrintIText(rp, inst->IText, l, t) ;
- break ;
- case DRAW_IMAGE:
- // ne pas afficher les images trop grandes pour le gadget
-
- if (inst->LabelImage->Width < g->Width &&
- inst->LabelImage->Height < g->Height) {
-
- // Centrage de l'image
- l = g->LeftEdge + (g->Width - inst->LabelImage->Width) / 2 ;
- t = g->TopEdge + (g->Height - inst->LabelImage->Height) / 2 ;
- DrawImageState(rp,
- inst->LabelImage,
- l, t,
- state,
- msg->gpr_GInfo->gi_DrInfo) ;
- }
- break ;
- }
- if (msg->MethodID != GM_RENDER)
- ReleaseGIRPort(rp) ;
-
- }
- else
- retval = FALSE ;
- return retval ;
- }
-
-
-